/*
 *
 *  Copyright (C) 2010 Tal Eisenberg
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package gui;

import java.awt.Color;
import java.awt.Font;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.util.Map;
import tal.drivechain.chain.AbortChainException;
import tal.drivechain.chain.Chain;
import tal.drivechain.chain.ChainNode;
import tal.drivechain.chain.NodeListener;
import tal.drivechain.gui.GUIContainer;
import tal.drivechain.plugin.Module;
import tal.drivechain.plugin.Channel;
import tal.drivechain.gui.GUIWindow;
import tal.drivechain.variable.SetProperty.Flag;
import tal.drivechain.variable.Variable;


/**
 *
 * @author Main
 */
public class Window extends Module implements WindowListener, GUIContainer {
    boolean visible = false;
    GUIWindow window;
    boolean exitOnHide;
    String id;
    private NodeListener metaListener;
    private boolean alwaysOnTop = false;

    public Window() {
        this.canHaveOutputs = false;
        window = new GUIWindow(false);
        metaListener = new NodeListener() {
            public void metaChanged(ChainNode src) {
                updateAboutText();
            }

            public void messageReceived(ChainNode src, Variable var, Channel channel, long timestamp) {}

            public void messageSent(ChainNode src, Variable var, long timestamp) {}

            public void nameChanged(ChainNode src) {}

            public void connectionsChanged(ChainNode src) {}

            public void nodeDestroyed(ChainNode src) {}

            public void nodeMoved(ChainNode src) {}

            public void propertyChanged(ChainNode src, String name, Object value) {}
        };
    }

    @Override
    public void setupProperties() throws IllegalArgumentException, AbortChainException {
//        List<PropertyInfo> kprops = this.nodeInfo.getProperties();
//        for (PropertyInfo i : kprops)
//            System.out.println(i.getName());
        window.addWindowListener(this);
        window.initWindow();
        super.setupProperties();
    }

    public void setId(String value) {
        if (isRunning())
            throw new IllegalArgumentException("Can't set id while chain is open.");
        if (getParentChain().getSharedObjects().containsValue(window.getModuleContainer()))
            getParentChain().getSharedObjects().remove(id);
        if (getParentChain().getSharedObjects().containsValue(window.getMenuContainer()))
            getParentChain().getSharedObjects().remove(id + ".menu");

        if (value!=null)
            id = value;
        else id = getName();

        getParentChain().getSharedObjects().put(id, window.getModuleContainer());
        getParentChain().getSharedObjects().put(id+".menu", window.getMenuContainer());
    } public String getId() { return id; }

    public void setX(Integer value) {
        window.setLocation((Integer)value, window.getY());
    } public int getX() { return window.getX(); }

    public void setY(Integer value) {
        window.setLocation(window.getX(), (Integer)value);
    } public int getY() { return window.getY(); }

    public void setColor(Color value) {
        window.setColor(value);
    } public Color getColor() { return window.getColor(); }

    public void setAlwaysOnTop(Boolean value, Flag flag) {
        System.out.println("SETTING ALWAYS ON TOP "  +value);
        alwaysOnTop = value;
        if (window.isVisible()) window.setAlwaysOnTop(value);
    } public boolean getAlwaysOnTop() { return alwaysOnTop; }

    public void setExitOnHide(Boolean value) {
        exitOnHide = value;
        window.setExitOnHide(exitOnHide);
    } public boolean getExitOnHide() { return exitOnHide; }

    public void setDecorate(Boolean value) {
        window.setDecorate(value);
    } public boolean getDecorate() { return window.isDecorated(); }

    public void setResizable(Boolean value, Flag flag) {
        window.setResizable(value);
    } public boolean getResizable() { return window.isResizable(); }

    public void setAnchorMenu(Boolean value) {
        window.setAnchorMenu(value);
    } public boolean getAnchorMenu() { return window.isMenuAnchored(); }

    public void setFont(Font value) {
        window.setFont(value);
    } public Font getFont() { return window.getFont(); }

    public void setTitle(String value) {
        if (value==null)
            window.setTitle((id==null)?this.nodeName:id);
        else window.setTitle(value);
    } public String getTitle() { return window.getTitle(); }

    public void setMenuBarVisible(Boolean value) {
        if (window!=null)
            window.setMenuBarVisible(value);
    } public Boolean getMenuBarVisible() {
        if (window!=null)
            return window.isMenuBarVisible();
        else return null;
    }

    public void setVisible(Boolean visible) {
        if (window!=null && isRunning())
            window.setVisible(visible);
        this.visible = visible;
        if (visible) window.setAlwaysOnTop(alwaysOnTop);
    } public boolean getVisible() { return visible; }

    @Override
    public void stop() {
        if (window!=null) window.setVisible(false);
    }

    @Override
    public void start() {
        super.start();
    }

    @Override
    public void destroy() {
        super.destroy();
        if (window!=null) window.dispose();
        getParentChain().getSharedObjects().remove(id);
        getParentChain().getSharedObjects().remove(id+".menu");
        getParentChain().removeNodeListener(metaListener);
    }

    @Override
    protected void msgReceived(Variable in, long timestamp, Channel channel) {
        if (in.getName().equals("init") && channel==Channel.GLOBALMESSAGE) {
            window.setVisible(visible);
            if (visible) window.setAlwaysOnTop(alwaysOnTop);
        }
    }
    
    public void windowOpened(WindowEvent e) {}

    public void windowClosed(WindowEvent e) { }

    public void windowClosing(WindowEvent e) {
        if (infoFlag)
            log("Window " + this.getName() + " is closed.", MSG.INFO);
        if (exitOnHide) {
            getParentChain().stop();
        }
    }

    public void windowIconified(WindowEvent e) {}

    public void windowDeiconified(WindowEvent e) {}

    public void windowActivated(WindowEvent e) {}

    public void windowDeactivated(WindowEvent e) {}

    @Override
    public void setParentChain(Chain parentChain) {
        if (parentChain==getParentChain()) return;
        
        if (getParentChain()!=null)
            getParentChain().removeNodeListener(metaListener);
        super.setParentChain(parentChain);
        getParentChain().addNodeListener(metaListener);
        updateAboutText();
    }

    private void updateAboutText() {
        String t = "chain " + getParentChain().getName() + "\n";
        Map<String,String> meta = getParentChain().getMetadataMap();
        for (String key : meta.keySet()) {
            if (!key.trim().startsWith("."))
                t += key + ": " + meta.get(key) + "\n";
        }
        window.setAboutText(t);
    }

    public void show() {
        if (isRunning()) {
            if (visible==false) setVisible(true);
            else window.setVisible(true);
        }
    }
}



